#include <iostream>
#include <fstream>
#include <iomanip>

#include <sys/types.h>
#include <fcntl.h>

#include "../timemeasure/timemeasure.h"

#include "IOError.h"
#include "DigitalIO_DL636F.h"
#include "Counter_DL636G1.h"
#include "TimeCounter_DL643A1.h"

char *devfn               = "/tmp/sis1100_00remote";
u_int32_t io1_addr        = 0x8800;
u_int32_t counter1_addr   = 0x8840;
u_int32_t tc_addr         = 0x8860;

int measure_time=60;
int sleep_time=1;

int main(int argc,char *argv[])
{
  cerr << "test_TimeCounter" << endl << endl;

  TM_INIT();
  cerr << "#cpu frequency: " << tm_cpu_freq << endl << endl;

  int crate;
  if( !(crate=open(devfn, O_RDWR, 0)) )
  {
    cerr << "ERROR: could not open \"" << devfn << "\"" << endl;
    exit(1);
  }
  
	cerr << setw(20) << "vmesysreset..." << flush;
	if(int r=vmesysreset(crate)) {
			cerr << "error: vmesysreset() returned " << r << endl << endl;
			cerr.flush(); exit(1);
	}
	sleep(1);
	cerr << "ok\n";

  DigitalIO_DL636F    io1(crate,io1_addr);
  Counter_DL636G1     counter1(crate,counter1_addr);
  TimeCounter_DL643A1 tc(crate,tc_addr);


  try {
    counter1.reset();
    tc.reset();
    
    cerr << "sleeping " << sleep_time << " sec"<< endl;
 
		io1.setO2(1); //enable counter1 via O2
    io1.setO4(1); //enable c    


		time_t start = time(0);
		double dt;
    while((dt=difftime(time(0),start)) < measure_time) {
				sleep(sleep_time);
		}

    io1.setO4(0); //disable tc
    io1.setO2(0); //disable counter1

    int count = counter1.getC();
    cerr << "counter c got " << count << " events" << endl << endl;

    //read out timecounter
    
    cerr << "timer counter fifo has " << tc.getWords() << " words" << endl;

#define DMA 1

#if DMA 
    cerr << "using DMA" << endl;

    u_int32_t *buf = new u_int32_t[tc.getWords()*2];

    TM_START();
    tc.readFIFO32DMA(tc.getWords()*2,buf);
    TM_STOP();

    cerr << "# cpu_freq: " << tm_cpu_freq << endl
         << "  cpu_ticks: " << tm_delta << endl
	 << " delta time: " << tm_secs << "sec  = "
	 << tm_secs*1000 << " ms" << endl << endl;

         

    for(int i=0; i<count*2; i+=2)
    {
				cout << dec << (i/2) << " " 
						 << (((buf[i+1] & 0x00ff) << 16) | (buf[i] & 0xffff))  << " "
						 << hex << buf[i+1] << " " << buf[i]  << endl;

      
				if(buf[i+1] & 0xc000)
						cerr << "error:" << hex << (buf[i+1] & 0xc000) << dec << endl;
     
				//cout << (i/2) << " " << TimeCounter_DL643A1::assemble(buf+i) << endl;
    }
#else
    cerr << "DMA disabled" << endl;

    for(int i=0; i <count; i++)
    {
				cout << i << " " << tc.readFIFO() << endl;
    }
#endif 

  } catch(IOError ioe) {
			cerr << "catched IOError exception: " << ioe.getMsg() << endl 
					 << "param=0x" << hex << ioe.getParam() << dec << endl << endl;

			cerr << "setting outputs of io1 to zero" << endl << endl;
			io1.setO2(0); io1.setO4(0);
  }

  close(crate);

  return 0;
}
